package com.gitee.wsl.mathematics.geometry.d2.poly.polygon

import com.gitee.wsl.mathematics.coordinate.d2.Coordinate2
import com.gitee.wsl.mathematics.geometry.api.PolygonShape
import com.gitee.wsl.mathematics.geometry.d2.CloseShape2d
import com.gitee.wsl.mathematics.geometry.d2.LineListShape2d

import com.gitee.wsl.mathematics.number.compareTo
import com.gitee.wsl.mathematics.vector.ext.plus

interface PolygonShape2d<T:Number,V: Coordinate2<T, V>>: PolygonShape<T, V>, LineListShape2d<T, V>,CloseShape2d<T,V>{

    override val center: V
        get() = TODO("Not yet implemented")

    override val area:T get() {
            var i = -1
            val size = size
            var b = last()
            var area = zero

            while (++i < size) {
                val a = b
                b = this[i]
                area += a.y * b.x - a.x * b.y
            }
            return area / 2
        }

    override fun containsPoint(p: Coordinate2<T, *>): Boolean {
        val size = size
        var p1 = last()
        val x = p.x
        val y = p.y
        var x0 = p1.x
        var y0 = p1.y
        var inside = false

        (0 until size).forEach { i ->
            p1 = this[i]
            val x1 = p1.x
            val y1 = p1.y
            if (((y1 > y) != (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside
            x0 = x1
            y0 = y1
        }

        return inside
    }
}

/**
 * Returns true if and only if the specified point is inside the polygon.
 */
/*
fun<T:Number,V: Coordinate2<T, V>> PolygonShape2d<T, V>.contains(point: Coordinate2<T, *>): Boolean {
    val size = size
    var p = last()
    val x = point.x
    val y = point.y
    var x0 = p.x
    var y0 = p.y
    var inside = false

    (0 until size).forEach { i ->
        p = this[i]
        val x1 = p.x
        val y1 = p.y
        if (((y1 > y) != (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside
        x0 = x1
        y0 = y1
    }

    return inside
}*/
